
 
import UIKit

extension String {
    
    func attributedString(rangeString: String, rangeColor: UIColor, margin: CGFloat = 0, alignment: NSTextAlignment = .left) -> NSAttributedString {
        
        let attributedText = NSMutableAttributedString(string: self)
                
        let nsString = self as NSString
        let range = nsString.range(of: rangeString)
        if range.location != NSNotFound {
            attributedText.addAttribute(.foregroundColor, value: rangeColor, range: range)
        }
 
        let paragraphStyle = NSMutableParagraphStyle()
        if margin > 0 {
            paragraphStyle.lineSpacing = margin
        }
        paragraphStyle.alignment = alignment
        attributedText.addAttribute(.paragraphStyle, value: paragraphStyle, range: NSRange(location: 0, length: self.count))
        return attributedText
    }
    
    
    func attributedString(rangeStrings: String..., rangeColor: UIColor, rangeFont: UIFont, color: UIColor, font: UIFont, margin: CGFloat = 0, alignment: NSTextAlignment = .left) -> NSAttributedString {
        
        let attributedText = NSMutableAttributedString(string: self)
        
        attributedText.addAttribute(.foregroundColor, value: color, range: NSRange(location: 0, length: self.count))
        attributedText.addAttribute(.font, value: font, range: NSRange(location: 0, length: self.count))
        
        // 设置指定字符串的颜色和字体
        for rangeString in rangeStrings {
            let nsString = self as NSString
            let range = nsString.range(of: rangeString)
            if range.location != NSNotFound {
                attributedText.addAttribute(.foregroundColor, value: rangeColor, range: range)
                attributedText.addAttribute(.font, value: rangeFont, range: range)
            }
        }
        
        let paragraphStyle = NSMutableParagraphStyle()
        if margin > 0 {
            paragraphStyle.lineSpacing = margin
        }
        paragraphStyle.alignment = alignment
        attributedText.addAttribute(.paragraphStyle, value: paragraphStyle, range: NSRange(location: 0, length: self.count))
        return attributedText
    }
    
    func titleMargin(_ magrin: CGFloat, font: UIFont? = UIFont.systemFont(ofSize: 14), alignment: NSTextAlignment = .left) -> NSAttributedString {
        
        var attributes: [NSAttributedString.Key : Any]? = nil
        if let textFont = font {
            attributes = [.font: textFont]
        }
        
        let attributedText = NSMutableAttributedString(string: self, attributes: attributes)
        let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.lineSpacing = magrin
        paragraphStyle.alignment = alignment
        attributedText.addAttribute(.paragraphStyle, value: paragraphStyle, range: NSRange(location: 0, length: self.count))
        return attributedText
    }
    
    func getSize(maxWidth: CGFloat, font: UIFont) -> CGSize {
        let attributes: [NSAttributedString.Key: Any] = [.font: font]
        let rect = self.boundingRect(with: CGSize(width: maxWidth, height: CGFLOAT_MAX),
                                     options: .usesLineFragmentOrigin,
                                     attributes: attributes,
                                     context: nil)
        return rect.size
    }
    
    func getSize(maxWidth: CGFloat) -> CGSize {
        let rect = self.boundingRect(with: CGSize(width: maxWidth, height: CGFLOAT_MAX),
                                     options: .usesLineFragmentOrigin,
                                     context: nil)
        return rect.size
    }
    
    func isBlank(using characterSet: CharacterSet = .whitespacesAndNewlines) -> Bool {
        return self.trimmingCharacters(in: characterSet).isEmpty
    }
    
    var removingCharacter: String {
        guard !self.isEmpty else { return "" }
        return self.replacingOccurrences(of: " ", with: "")
    }

    var firstCharacter: String {
        guard !self.isEmpty else { return "" }
        return String(self.prefix(1))
    }
    
    var lastCharacter: String {
        guard !self.isEmpty else { return "" }
        return String(self.suffix(1))
    }
    
    var removingFirstCharacter: String {
        guard !self.isEmpty else { return "" }
        return String(self.dropFirst())
    }
    
    var removingLastCharacter: String {
        guard !self.isEmpty else { return "" }
        return String(self.dropLast())
    }
    
    var trimmed: String {
        return self.trimmingCharacters(in: .whitespacesAndNewlines)
    }
    
    var deletingLastPathComponent: String {
        return (self as NSString).deletingLastPathComponent
    }
    
    var deletingPathExtension: String {
        return (self as NSString).deletingPathExtension
    }
     
    var pathExtension: String {
        return (self as NSString).pathExtension
    }
    
    func removingMarkdown() -> String {
        var result = self

        let patterns: [String: String] = [
            "\\s?\\*\\*(.*?)\\*\\*\\s?"     : "$1", // **bold**
            "\\s?\\*(.*?)\\*\\s?"           : "$1", // *italic*
            "\\s?__(.*?)__\\s?"             : "$1", // __bold__
            "\\s?_(.*?)_\\s?"               : "$1", // _italic_
            "\\s?~~(.*?)~~\\s?"             : "$1", // ~~strikethrough~~
            "\\s?`{1,3}[^`]*`{1,3}\\s?"     : "",   // `code` 或 ```code``` 清除整段
            "^#+\\s*"                       : "",   // # title
            "^>\\s*"                        : "",   // > quote
            "\\s?\\$begin:math:display\\$(.*?)\\$end:math:display\\$begin:math:text\\$(.*?)\\$end:math:text\\$\\s?" : "$1",
            "\\s?!\\$begin:math:display\\$(.*?)\\$end:math:display\\$begin:math:text\\$(.*?)\\$end:math:text\\$\\s?" : "",  // 图片
        ]

        for (pattern, template) in patterns {
            result = result.replacingOccurrences(
                of: pattern,
                with: template,
                options: [.regularExpression, .caseInsensitive]
            )
        }

        // 移除多余的空白字符（多个空格、前后空格、换行）
        result = result.replacingOccurrences(of: "\\s{2,}", with: " ", options: .regularExpression)
        return result.trimmingCharacters(in: .whitespacesAndNewlines)
    }
}


// MARK: - String Extension
extension String {
    
    /// Caches 目录下的路径
    var cachePath: String {
        let cachesDir = NSSearchPathForDirectoriesInDomains(.cachesDirectory, .userDomainMask, true).last!
        return (cachesDir as NSString).appendingPathComponent(lastPathComponent)
    }
    
    /// Documents 目录下的路径
    var documentsPath: String {
        let documentsDir = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).last!
        return (documentsDir as NSString).appendingPathComponent(lastPathComponent)
    }
    
    /// Temporary 目录下的路径
    var temporaryPath: String {
        (NSTemporaryDirectory() as NSString).appendingPathComponent(lastPathComponent)
    }
    
    /// 获取最后一个路径组件
    var lastPathComponent: String {
        (self as NSString).lastPathComponent
    }
    
    private static let currentLibraryPath: String? = {
        NSSearchPathForDirectoriesInDomains(.libraryDirectory, .userDomainMask, true).last
    }()
    
    var realFilePath: String {
        if let libraryDirectory = Self.currentLibraryPath, let lastPath = self.components(separatedBy: "Library").last {
            return libraryDirectory + lastPath
        } else {
            return self
        }
    }

}


extension NSAttributedString {
    func getSize(maxWidth: CGFloat) -> CGSize {
        let constraintRect = CGSize(width: maxWidth, height: .greatestFiniteMagnitude)
        let boundingBox = self.boundingRect(
            with: constraintRect,
            options: [.usesLineFragmentOrigin, .usesFontLeading],
            context: nil
        )
        return CGSize(width: ceil(boundingBox.width), height: ceil(boundingBox.height))
    }
}


extension NSMutableAttributedString {
    func setColor(for text: String, color: UIColor) {
        let fullRange = NSString(string: self.string).range(of: text)
        if fullRange.location != NSNotFound {
            addAttribute(.foregroundColor, value: color, range: fullRange)
        }
    }
    
    func setFont(for text: String, font: UIFont) {
        let fullRange = NSString(string: self.string).range(of: text)
        if fullRange.location != NSNotFound {
            addAttribute(.font, value: font, range: fullRange)
        }
    }
}


extension String {
    func toObject() -> Any? {
        guard let data = self.data(using: .utf8) else { return nil }
        return try? JSONSerialization.jsonObject(with: data, options: [])
    }
    
    var boolValue: Bool {
        return self == "1" || self.lowercased() == "true"
    }
}


extension String {
    func formattedDecimal(decimals: Int, useGrouping: Bool = true) -> String {
        guard let number = Double(self) else { return self }
        
        let formatter = NumberFormatter()
        formatter.minimumFractionDigits = decimals   // 最少小数位
        formatter.maximumFractionDigits = decimals   // 最多小数位
        formatter.numberStyle = .decimal
        if !useGrouping {
            formatter.groupingSeparator = ""
        }
        return formatter.string(from: NSNumber(value: number)) ?? self
    }
    
    /// 字符串数字相乘，返回结果字符串
    /// - Parameter other: 另一个数字字符串
    /// - Returns: 相乘后的结果字符串
    func multiply(_ other: String) -> String {
        let num1 = NSDecimalNumber(string: self)
        let num2 = NSDecimalNumber(string: other)
        return num1.multiplying(by: num2).stringValue
    }
}
